/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.songlanyun.modules.user.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.DateUtils;
import com.songlanyun.common.utils.R;
import com.songlanyun.common.utils.RedisKeys;
import com.songlanyun.common.utils.custom.ClassConvertUtils;
import com.songlanyun.modules.sensitivelog.entity.SensitiveLog;
import com.songlanyun.modules.sensitivelog.service.SensitiveLogService;
import com.songlanyun.modules.user.dao.SysUserDao;
import com.songlanyun.modules.user.entity.SysUserEntity;
import com.songlanyun.modules.user.exception.UserException;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Controller公共组件
 *
 * @author Mark sunlightcs@gmail.com
 */
public abstract class AbstractController {

    @Autowired
    HttpServletRequest request;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    private SensitiveLogService sensitiveLogService;
    @Resource
    private SysUserDao sysUserDao;


    protected Logger logger = LoggerFactory.getLogger(getClass());

    protected SysUserEntity getUser() {
        return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
    }

    protected Long getUserId() {
        return getUser().getUserId();
    }

    protected Long getUserIdByRequest() {
        String uid = (String) request.getAttribute("uid");
        return Long.parseLong(uid);
    }

    protected Long getShopId() {
        Object shopId = request.getAttribute("shop_id");
        if (shopId != null) {
            return Long.valueOf(shopId.toString());
        }

        return 0L;
    }

    /**
     * 获得店铺商家id
     *
     * @param isThrow
     * @return
     */
    protected Long getShopId(boolean isThrow) {
        Object shopId = request.getAttribute("shop_id");
        if (shopId != null) {
            return Long.valueOf(shopId.toString());
        }
        if (isThrow) {
            throw new RRException("商家才能操作");
        }
        return 0L;
    }

    /**
     * 获得区域代理id
     * @return
     */
    protected Long getAreaAgentId() {
        Object areaAgentId = request.getAttribute("area_agent_id");
        if (areaAgentId != null) {
            return Long.valueOf(areaAgentId.toString());
        }

        return 0L;
    }

    /**
     * 获得区域代理id
     *
     * @param isThrow
     * @return
     */
    protected Long getAreaAgentId(boolean isThrow) {
        Object areaAgentId = request.getAttribute("area_agent_id");
        if (areaAgentId != null) {
            return Long.valueOf(areaAgentId.toString());
        }
        if (isThrow) {
            throw new RRException("区域代理才能操作");
        }
        return 0L;
    }

    /**
     * 是否是商家管理员
     * true :商家管理员
     * false：平台管理员
     */
    protected boolean isShop() {
        return getUser().getIsShop();//是否是商家管理员
    }

    /**
     * 设置创建者ID
     *
     * @param params
     */
    protected void setCreateUserId(Map<String, Object> params) {
        //平台管理员查询所有用户
        //商家管理员查询商家创建的管理员
        if (isShop()) {
            params.put("createUserId", getUserId());
        }
    }

    /**
     * 平台管理员才能操作
     * <p>
     * 不是商家管理员，就是平台管理员
     *
     * @return
     */
    protected void verifyAdmin() {
        if (isShop()) {
            throw new RRException(UserException.ADMIN_OPERATION);
        }
    }

    /**
     * 校验商家，当前商家才能操作
     *
     * @param shopId
     */
    protected void verifyShopId(Long shopId) {
        if (!getShopId().equals(shopId)) {
            throw new RRException(UserException.CURRENT_USER_NOT_DEL);
        }
    }

    protected SysUserEntity getUserInfo(boolean isThrow) {
        SysUserEntity user = getUser();
        if (user == null) {
            if (isThrow) {
                throw new RRException(UserException.USER_NOT_EXISTS);
            }
        }
        return user;
    }

    /**
     * 创建敏感日志
     *
     * @param remark
     */
    protected void sensitiveLogCreate(String remark) {
        SensitiveLog log = new SensitiveLog(getUserInfo(true).getUsername(), remark);
        sensitiveLogService.save(log);
    }

    /**
     * 设置商家id
     *
     * @param params
     */
    protected void setShopId(Map<String, Object> params) {
        if (isShop()) {
            params.put("shop_id", getShopId());
        }
    }


    protected Long getAdminByToken(HttpServletResponse response) throws IOException {

        String token = request.getParameter("token");
        if (!StringUtils.hasText(token)) {
            response.setCharacterEncoding("UTF-8"); //设置编码格式
            response.setContentType("application/json");
            R responseBean = R.error(-400, "访问需要令牌");
            response.getWriter().write(JSON.toJSONString(responseBean));
            throw new RRException("访问需要令牌");
        } else {
            String uid = redisTemplate.opsForValue().get(RedisKeys.getTokenConfigKey(token));
            if (!org.apache.commons.lang.StringUtils.isNotBlank(uid)) {
                response.setCharacterEncoding("UTF-8"); //设置编码格式
                response.setContentType("application/json");
                R responseBean = R.error(-401, "非法操作");
                response.getWriter().write(JSON.toJSONString(responseBean));
                throw new RRException("非法操作");
            } else {
                return ClassConvertUtils.objToLong(uid);
            }
        }

    }

    protected void export(HttpServletResponse response, Class<?> clazz, Collection<?> list, String title) throws IOException {
        String fileName = title + DateUtils.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(3) + "." + "xls";
        ExportParams exportParams = new ExportParams(title + "导出(" + list.size() + ")", title);

        Workbook sheets = ExcelExportUtil.exportExcel(exportParams, clazz, list);
        response.setContentType(new MimetypesFileTypeMap().getContentType("application/octet-stream"));// 设置response内容的类型

        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));// 设置头部信息
        sheets.write(response.getOutputStream());
        sheets.close();
    }


}
